﻿using ChoiceTech.Halcon.Control;
using DevExpress.Data.Filtering.Helpers;
using HalconDotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static DevExpress.Utils.Svg.CommonSvgImages;

namespace HTHMachineVision
{
    public class MeasureTool
    {
        
        /// <summary>
        /// 直线测量功能
        /// </summary>
        /// <param name="hImage">输入测量图像</param>
        /// <param name="lineData">输入测量工具数据</param>
        /// <param name="hXLDCont_小卡尺"></param>
        /// <param name="row_小卡尺"></param>
        /// <param name="col_小卡尺"></param>
        /// <param name="hXLDCont_直线"></param>
        /// <param name="rowStart_直线"></param>
        /// <param name="colStart_直线"></param>
        /// <param name="rowEnd_直线"></param>
        /// <param name="colEnd_直线"></param>
        /// <returns>测量结果 true成功 | false失败 </returns>
        public static bool MLine(HImage hImage, GraphicalData lineData, 
                                out HXLDCont hXLDCont_小卡尺, out HTuple row_小卡尺, out HTuple col_小卡尺,
                                out HXLDCont hXLDCont_直线, out HTuple rowStart_直线, out HTuple colStart_直线, out HTuple rowEnd_直线, out HTuple colEnd_直线)
        {
            //2.创建测量模型
            //HOperatorSet.CreateMetrologyModel(out HTuple metrologyHandle);
            HMetrologyModel hMetrologyModel = new HMetrologyModel();


            //3.添加测量工具到模型中
            int index = hMetrologyModel.AddMetrologyObjectLineMeasure(
                lineData.Measure_lineSatrtRow, 
                lineData.Measure_lineSatrtCol, 
                lineData.Measure_lineEndRow, 
                lineData.Measure_lineEndCol,
                lineData.Measure_length1,
                lineData.Measure_length2, 
                1,
                lineData.Measure_threshold, 
                new HTuple(), new HTuple());

            //4.设置工具参数
            hMetrologyModel.SetMetrologyObjectParam(index, "measure_length1", lineData.Measure_length1);
            hMetrologyModel.SetMetrologyObjectParam(index, "measure_length2", lineData.Measure_length2);
            hMetrologyModel.SetMetrologyObjectParam(index, "measure_distance", lineData.Measure_distance);
            hMetrologyModel.SetMetrologyObjectParam(index, "measure_threshold", lineData.Measure_threshold);
            hMetrologyModel.SetMetrologyObjectParam(index, "measure_transition", lineData.Measure_transition);
            hMetrologyModel.SetMetrologyObjectParam(index, "measure_select", lineData.Measure_select);
            hMetrologyModel.SetMetrologyObjectParam(index, "min_score", 0.3);//测量工具得分

            //5.应用测量模型
            hMetrologyModel.ApplyMetrologyModel(hImage);

            //6.获取测量结果（小卡尺，测量工具结果）

            //小卡尺轮廓结果 （小卡尺结果 c#里面所有 xld都用 HXLDCont 类型）
            hXLDCont_小卡尺 = hMetrologyModel.GetMetrologyObjectMeasures(index, "all", out row_小卡尺, out col_小卡尺);

            //十字架显示轮廓
            //HXLDCont hxldCont1 = new HXLDCont();
            //hxldCont1.GenCrossContourXld(row, column, 2, 0.78);

            //可视化 显示小卡尺轮廓 和小卡尺点 
            //hWindow_Final1.DispObj(hXLDCont, "blue");
            //hWindow_Final1.DispObj(hxldCont1, "green");

            //获取直线测量结果
            // res 结果：直线起点
            HTuple res = hMetrologyModel.GetMetrologyObjectResult(index, "all", "result_type", "all_param");
            //直线测量结果轮廓
            hXLDCont_直线 = hMetrologyModel.GetMetrologyObjectResultContour(index, "all", 1.5);

            rowStart_直线 = 0;
            colStart_直线 = 0;
            rowEnd_直线 = 0;
            colEnd_直线 = 0;

            //直线测量有结果
            if (res.Length > 3)
            {
                rowStart_直线 = res[0].D;
                colStart_直线 = res[2].D;
                rowEnd_直线 = res[1].D;
                colEnd_直线 = res[3].D;

                return true;
                //HXLDCont hxldCont3 = new HXLDCont();
                //hxldCont3.GenCrossContourXld(new HTuple(res[0].D, res[2]), new HTuple(res[1].D, res[3]), 5, 0.78);

                //hWindow_Final1.DispObj(hxldCont2, "red");
                //hWindow_Final1.DispObj(hxldCont3, "yellow");
            }
            else
            {
                return false;
            }

        }

        //仿射变换功能
        public static GraphicalData MLineAffine(HHomMat2D hHomMat2D, GraphicalData lineData)
        {
            //使用深度拷贝
            GraphicalData lineData1 = MyTool.DeepCopyByBinary<GraphicalData>(lineData);

            //对直线起点进行仿射变换
            lineData1.Measure_lineSatrtRow = hHomMat2D.AffineTransPoint2d(
                lineData1.Measure_lineSatrtRow,
                lineData1.Measure_lineSatrtCol,
                out lineData1.Measure_lineSatrtCol);

            //对直线终点进行仿射变换
            //lineData1.Measure_lineSatrtRow
            lineData1.Measure_lineEndRow = hHomMat2D.AffineTransPoint2d(
                lineData1.Measure_lineEndRow,
                lineData1.Measure_lineEndCol,
                out lineData1.Measure_lineEndCol);

            return lineData1;
        }


        /// <summary>
        /// 矩形测量
        /// </summary>
        /// <param name="hImage"></param>
        /// <param name="lineData"></param>
        /// <param name="hXLDCont"></param>
        /// <param name="hxldCont1"></param>
        /// <param name="res"></param>
        /// <param name="hxldCont2"></param>
        /// <returns></returns>
        public static bool MeasureRectangle(HImage hImage, GraphicalData lineData,
            out HXLDCont hXLDCont,out HXLDCont hxldCont1,out HTuple resRow, out HTuple resCol, out HXLDCont hxldCont2)
        {
            //2.创建测量模型
            HMetrologyModel hMetrologyModel = new HMetrologyModel();

            //3.添加测量工具到模型中
            int index = hMetrologyModel.AddMetrologyObjectRectangle2Measure(
                lineData.RectangleRow, lineData.RectangleColumn, lineData.RectanglePhi, lineData.RectangleLength1, lineData.RectangleLength2,
                lineData.Measure_length1, lineData.Measure_length2, 1,
                lineData.Measure_threshold, new HTuple(), new HTuple());

            //4.设置工具参数
            hMetrologyModel.SetMetrologyObjectParam(index, "measure_length1", lineData.Measure_length1);
            hMetrologyModel.SetMetrologyObjectParam(index, "measure_length2", lineData.Measure_length2);
            hMetrologyModel.SetMetrologyObjectParam(index, "measure_distance", lineData.Measure_distance);
            hMetrologyModel.SetMetrologyObjectParam(index, "measure_threshold", lineData.Measure_threshold);
            hMetrologyModel.SetMetrologyObjectParam(index, "measure_transition", lineData.Measure_transition);
            hMetrologyModel.SetMetrologyObjectParam(index, "measure_select", lineData.Measure_select);
            hMetrologyModel.SetMetrologyObjectParam(index, "min_score", 0.3); // 测量工具得分

            //5.应用测量模型
            hMetrologyModel.ApplyMetrologyModel(hImage);

            //6.获取测量结果（小卡尺，测量工具结果）
            Console.WriteLine("Attempting to get measures...");
            // 小卡尺轮廓结果 （小卡尺结果 c#里面所有 xld都用 HXLDCont 类型）
            hXLDCont = hMetrologyModel.GetMetrologyObjectMeasures(index, "all", out HTuple row1, out HTuple column1);
            Console.WriteLine($"Got {row1.Length} rows and {column1.Length} columns.");

            // 十字架显示轮廓
            hxldCont1 = new HXLDCont();
            hxldCont1.GenCrossContourXld(row1, column1, 2, 0.78);

            // 获取矩形测量结果
            // res 结果：中心点坐标 + 角度、半宽、半高
            HTuple res = hMetrologyModel.GetMetrologyObjectResult(index, "all", "result_type", "all_param");
            Console.WriteLine($"Result tuple length is {res.Length}.");
            // 矩形测量结果轮廓
            hxldCont2 = hMetrologyModel.GetMetrologyObjectResultContour(index, "all", 1.5);

            resRow = 0;
            resCol = 0;
            if (res.Length > 4)
            {
                resRow = res[0];
                resCol = res[1];
                Console.WriteLine($"Measurement successful with center at ({resRow.D}, {resCol.D}).");
                return true;
            }
            else
            {
                Console.WriteLine("Measurement failed or no result available.");
                return false;
            }
        }

    }
}
